package com.rraj.apiversion;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.servlet.mvc.condition.RequestCondition;

/**
 * 版本号匹配筛选器
 *
 * @author WangSheng
 * @date 2017/06/20
 */
public class ApiVesrsionCondition implements RequestCondition<ApiVesrsionCondition> {

    /**
     * 路径中版本的正则匹配
     * /v[0-9]+.[0-9]+
     */
    private final static Pattern VERSION_PREFIX_PATTERN = Pattern.compile("/v(\\d+\\.\\d+)");

    private String apiVersion;

    public ApiVesrsionCondition(String apiVersion) {
        this.apiVersion = apiVersion;
    }

    @Override
    public ApiVesrsionCondition combine(ApiVesrsionCondition other) {
        // 采用最后定义优先原则，则方法上的定义覆盖类上面的定义
        return new ApiVesrsionCondition(other.getApiVersion());
    }

    @Override
    public int compareTo(ApiVesrsionCondition other, HttpServletRequest request) {
        // 优先匹配最新的版本号
        return other.getApiVersion().compareTo(this.apiVersion);
    }

    public String getApiVersion() {
        return apiVersion;
    }

    @Override
    public ApiVesrsionCondition getMatchingCondition(HttpServletRequest request) {
        Matcher m = VERSION_PREFIX_PATTERN.matcher(getRequestPath(request));
        if (m.find()) {
            String version = m.group(1);
            // 如果请求的版本号大于等于配置版本号则匹配，实现服务降级
            if (version.compareTo(this.apiVersion) >= 0){
                return this;
            }
        } else {
            // 如果版本号错误返回最新版本号
            return null;
        }
        return null;
    }

    private String getRequestPath(HttpServletRequest request){
        String uri = request.getRequestURI();
        String contextPath = request.getContextPath();
        if (contextPath != null && contextPath.length() > 0) {
            uri = uri.substring(contextPath.length());
        }
        return uri;
    }

}